package it.polimi.swKnights.SWIMv2.ejb.feedbacks;

import it.polimi.swKnights.SWIMv2.ejb.authentication.LoginHandlerLocal;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.Feedback;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.HelpRequest;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.HelpRequestPk;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.RegisteredUser;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.InvalidLoginPrivilegesException;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.LoginFailException;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.NoMatchingHelpRequest;
import it.polimi.swKnights.SWIMv2.utility.DateUtility;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 * Session Bean implementation class LeaveFeedbackHandler
 */
@Stateless
public class LeaveFeedbackHandler implements LeaveFeedbackHandlerRemote
{

	@EJB
	private LoginHandlerLocal loginController;

	@PersistenceContext(unitName = "swimv2-manager")
	private EntityManager managerUC; // manager handlin the persistence data

	@Override
	public void leaveFeedback(int idHelp, String gotBy, Integer rank,
			String text, String userNameLefting, String passwordLefting)
			throws LoginFailException, InvalidLoginPrivilegesException,
			NoMatchingHelpRequest
	{

		this.loginController.checkLoginDataAndPrivileges(userNameLefting,
				passwordLefting, RegisteredUser.class);
		this.loginController.checkBanned(userNameLefting);

		this.checkExistingHelpRequest(idHelp, userNameLefting, gotBy);
		
		this.deleteHelpRequest(idHelp, userNameLefting, gotBy);

		RegisteredUser gotByUser = null;
		RegisteredUser leftByUser = null;

		gotByUser = managerUC.find(RegisteredUser.class, gotBy);

		leftByUser = managerUC.find(RegisteredUser.class, userNameLefting);

		Feedback feedback = null;

		feedback = new Feedback(this.getID(gotByUser), gotByUser, rank,
				leftByUser);
		feedback.setText(text);

		managerUC.persist(feedback);
	}

	private void deleteHelpRequest(int idHelp, String asking,
			String answering) {
		HelpRequestPk key = new HelpRequestPk();
		key.setAnsweringUser(answering);
		key.setAskingUser(asking);
		key.setId(idHelp);

		HelpRequest help = this.managerUC.find(HelpRequest.class, key);
		
		this.managerUC.remove(help);
		
	}

	private void checkExistingHelpRequest(int idHelp, String asking,
			String answering) throws NoMatchingHelpRequest
	{
		HelpRequestPk key = new HelpRequestPk();
		key.setAnsweringUser(answering);
		key.setAskingUser(asking);
		key.setId(idHelp);
		
		HelpRequest help = this.managerUC.find(HelpRequest.class, key);

		if (help == null)
		{
			throw new NoMatchingHelpRequest();
		}
		
		if(!DateUtility.checkBetween(help.getEndDate(), 30))
		{
			
			throw new NoMatchingHelpRequest();
		}

	}

	private long getID(RegisteredUser gotByUser)
	{
		String countQuery = "SELECT COUNT(f) FROM Feedback AS f "
				+ "WHERE f.gotBy = :user";
				
		Query counter = this.managerUC.createQuery(countQuery);
		
		if(countQuery.contains(":user"))
		{
			counter.setParameter("user", gotByUser.getUserName());
		}
		
		Long count = (Long) counter.getSingleResult();

		if (count == 0)
		{
			return 0;
		}

		String idQuery = "" + "SELECT MAX(f.id) FROM Feedback AS f "
				+ "WHERE f.gotBy = :user";

		Query query = this.managerUC.createQuery(idQuery);

		query.setParameter("user", gotByUser.getUserName());

		return (Long) query.getSingleResult() + 1;
	}

}
